home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 15 / BBS in a box XV-2.iso / Files II / Prog / N-P / OOP for C.sit / OIC.ƒ / list.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-12-09  |  5.5 KB  |  299 lines  |  [TEXT/KAHL]

  1. /*    
  2.  *        List abstract class
  3.  *
  4.  *            Copyright © John Wainwright 1988
  5.  *
  6.  *        head l            - returns first item in list l
  7.  *        tail l            - returns list l minus 1st item
  8.  *        append l item    - appends item to list l
  9.  *        push l item     - pushes item on front of l
  10.  *        join l1 l2        - joins list2 to end of list1
  11.  *        isEmpty l        - returns non-zero if list is empty, ,zero if not
  12.  *        eq l1 l2        - test isomorphic equality between l1 & l2
  13.  *        new l itemlist    - builds new list
  14.  *        add l itemList    - adds items to list
  15.  *        nth i l            - nth item in list
  16.  *        second l        - second item in list
  17.  *        third l            - third item in list
  18.  *      sequence l        - returns an initialised sequence object containing l
  19.  *        map l f            - maps function over each element of l
  20.  *        copy l            - returns a new list which is a copy of l
  21.  *        deepCopy l        - returns a deep copy of l
  22.  *        dispose l        - disposes the list structure l (but not the items)
  23.  *        deepDispose l    - dispose l and sends 'deepDispose' to all it contains
  24.  *        print l            - outputs nicely formatted list l to stdout
  25.  *        repList l        - returns a representation (ascii) list for l
  26.  */
  27.  
  28. #include "oic.h"
  29. #include "generics.h"
  30.  
  31. class       List;            /* the list class                         */
  32.  
  33. typedef struct                /* list instance structure                 */
  34. {
  35.     list      l_next;
  36.     object    l_item;
  37. } list_i;
  38.  
  39. /* -------------------- List Instance methods ---------------------------- */
  40.  
  41. static list  
  42. _new(self, l, items)
  43.     object            self;
  44.     register list_i    *l;
  45.     register object    *items;
  46. {
  47.     while (*items != END)
  48.         append(self, *items++);
  49.         
  50.     return Super(self);
  51. }
  52.  
  53. static object
  54. _head(self, list)   
  55.     object            self;
  56.     register list_i *list;
  57. {
  58.     return list->l_item;
  59. }
  60.  
  61. static list  
  62. _tail(self, list)
  63.     object             self;
  64.     register list_i    *list;
  65. {
  66.     return (list->l_item == END) ? self : list->l_next;
  67. }
  68.  
  69. static list  
  70. _append(self, l, item)
  71.     object            self;
  72.     register list_i    *l;
  73.     object            *item;
  74. {
  75.     register list_i *li;
  76.  
  77.     for (li = l; li->l_item != END; li = localIVs(li->l_next, list_i));
  78.     li->l_next = New(List, END);
  79.     li->l_item = *item;
  80.  
  81.     return self;
  82. }
  83.  
  84. static list  
  85. _join(self, l, list2)
  86.     object            self;
  87.     register list_i    *l;
  88.     object            *list2;
  89. {
  90.     register list_i *l1, *l2;
  91.  
  92.     l2 = localIVs(*list2, list_i);
  93.     for (l1 = l; l1->l_item != END; l1 = localIVs(l1->l_next, list_i));
  94.     l1->l_next = l2->l_next;
  95.     l1->l_item = l2->l_item;
  96.  
  97.     return self;
  98. }
  99.  
  100. static list  
  101. _push(self, l, item)
  102.     object            self;
  103.     register list_i    *l;
  104.     object            *item;
  105. {
  106.     register list      newl;
  107.     register list_i *newinst;
  108.  
  109.     newl = New(List, END);
  110.     newinst = localIVs(newl, list_i);
  111.     newinst->l_next = l->l_next;
  112.     newinst->l_item = l->l_item;
  113.     l->l_next = newl;
  114.     l->l_item = *item;
  115.  
  116.     return self;
  117. }
  118.  
  119. static int
  120. _isEmpty(self, l)
  121.     object            self;
  122.     register list_i *l;
  123. {
  124.     return (l->l_item == END);
  125. }
  126.  
  127. static int
  128. _eq(self, l, otherlist)
  129.     object    self;
  130.     list_i    *l;
  131.     list      *otherlist;
  132. {
  133.     register object    head1, head2;
  134.  
  135.     head1 = head(self);
  136.     head2 = head(*otherlist);
  137.     
  138.     if (head1 == END && head2 == END)
  139.         return 1;
  140.     if (head1 == END || head2 == END)
  141.         return 0;
  142.     if ((int)eq(head1, head2))
  143.         return ((int)eq(tail(self), tail(*otherlist)));
  144.     else
  145.         return 0;
  146. }
  147.  
  148. static list  
  149. _add(self, l, items)
  150.     object            self;
  151.     register list_i    *l;
  152.     register object    *items;
  153. {
  154.     while (*items != END)
  155.         append(self, *items++);
  156.         
  157.     return self;
  158. }
  159.  
  160. static object
  161. _sequence(self)
  162.     object    self;
  163. {
  164.     return start(New(Linkseq), self);
  165. }
  166.  
  167. static object
  168. _assoc(self, l, key)
  169.     object            self;
  170.     register list_i    *l;
  171.     object            *key;
  172. {
  173.     register list_i *lp;
  174.  
  175.     for (lp = l; lp->l_item != END; lp = localIVs(lp->l_next, list_i))
  176.         if (ClassOf(lp->l_item) == List && eq(head(lp->l_item), *key))
  177.             return head(tail(lp->l_item));
  178.     
  179.     return END;
  180. }
  181.     
  182. static object
  183. _nth(self, l, n)
  184.     object            self;
  185.     register list_i    *l;
  186.     int                *n;
  187. {
  188.     register list_i *lp;
  189.     register int    i;
  190.  
  191.     for (lp = l, i = 0; i < *n && lp->l_item != END; i++, lp = localIVs(lp->l_next, list_i))
  192.         ;
  193.     
  194.     return lp->l_item;
  195. }
  196.     
  197. static object
  198. _second(self)
  199.     object            self;
  200. {
  201.     return head(tail(self));
  202. }
  203.     
  204. static object
  205. _third(self)
  206.     object            self;
  207. {
  208.     return head(tail(tail(self)));
  209. }
  210.     
  211. static object
  212. _repList(self, l, ap)
  213.     object    self;
  214.     list_i    *l;
  215.     void    *ap;
  216. {
  217.     register list_i *lp;
  218.     register object    replist;
  219.  
  220.     replist = New(Replist, "(", ")", " ");
  221.     if (l->l_item == END)
  222.         append(replist, New(String, "EMPTY"));
  223.     else
  224.     {
  225.         for (lp = l; lp->l_item != END; lp = localIVs(lp->l_next, list_i))
  226.             append(replist, repList(lp->l_item));
  227.     }
  228.  
  229.     return replist;
  230. }
  231.  
  232. static
  233. _deepDispose(self, li, ap)
  234.     object            self;
  235.     register list_i    *li;
  236.     void            *ap;
  237. {
  238.     register object    lo, nextl;
  239.  
  240.     if (li->l_item != END)
  241.     {
  242.         deepDispose(li->l_item);
  243.         for (lo = li->l_next; (li = (localIVs(lo, list_i)))->l_item != END; lo = nextl)
  244.         {
  245.             nextl = li->l_next;
  246.             deepDispose(li->l_item);
  247.             free(lo);
  248.         }
  249.     }
  250.     
  251.     free(self);
  252. }
  253.     
  254. static
  255. _dispose(self, li)
  256.     object            self;
  257.     register list_i    *li;
  258. {
  259.     register object    lo, nextl;
  260.  
  261.     if (li->l_item != END)
  262.     {
  263.         for (lo = li->l_next; (li = (localIVs(lo, list_i)))->l_item != END; lo = nextl)
  264.         {
  265.             nextl = li->l_next;
  266.             free(lo);
  267.         }
  268.     }
  269.     
  270.     free(self);
  271. }
  272.     
  273. /* ------------------- Init the List class ------------------------------- */
  274.  
  275. _InitList()
  276. {
  277.     List = NewClass(sizeof(list_i), 0, "List", END);
  278.     AddMethods(List,
  279.         appendGeneric,         _append,
  280.         joinGeneric,         _join,
  281.         pushGeneric,        _push,
  282.         headGeneric,        _head,
  283.         tailGeneric,        _tail,
  284.         assocGeneric,        _assoc,
  285.         nthGeneric,            _nth,
  286.         secondGeneric,        _second,
  287.         thirdGeneric,        _third,
  288.         isEmptyGeneric,        _isEmpty,
  289.         eqGeneric,            _eq,
  290.         sequenceGeneric,    _sequence,
  291.         disposeGeneric,        _dispose,
  292.         deepDisposeGeneric, _deepDispose,
  293.         newGeneric,            _new,
  294.         addGeneric,            _add,
  295.         repListGeneric,        _repList,
  296.         END);
  297. }
  298.  
  299.